package com.seal.commons.copiers.cglib;

import com.seal.commons.copiers.AbstractCopier;
import com.seal.commons.copiers.exception.CopierException;
import com.seal.commons.copiers.util.ReflectionUtil;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.beans.BeanCopier;
import net.sf.cglib.core.Converter;

import static com.seal.commons.copiers.util.Preconditions.checkNotNull;

/**
 * 功能描述: <br/>
 *
 * @author huangyong
 * @date: 2020-05-31 21:46<br/>
 * @since JDK 1.8
 */
@Getter
@Slf4j
public class CglibCopier<S, T> extends AbstractCopier<BeanCopier, S, T> {

    /** 自定义转换器，只有在 useConverter 为 true 时生效 */
    private Converter converter;

    public CglibCopier(Class<S> sourceClass, Class<T> targetClass) {
        // 创建 BeanCopier 对象，不使用转换器
        super(sourceClass, targetClass, BeanCopier.create(sourceClass, targetClass, false));
    }

    public CglibCopier(Class<S> sourceClass, Class<T> targetClass, Converter converter) {
        // 创建 BeanCopier 对象，使用转换器
        super(sourceClass, targetClass, BeanCopier.create(sourceClass, targetClass, true));
        this.converter = converter;
    }


    @Override
    public T copy(S source) {
        checkNotNull(source, "source bean cannot be null!");
        try {
            T target = ReflectionUtil.newInstance(targetClass);
            copier.copy(source, target, converter);
            return target;
        } catch (Exception e) {
            throw new CopierException("create object fail, class: " + targetClass.getName(), e);
        }
    }

    @Override
    public void copy(S source, T target) {
        checkNotNull(source, "source bean cannot be null!");
        checkNotNull(target, "target bean cannot be null!");
        try {
            copier.copy(source, target, converter);
        } catch (Exception e) {
            throw new CopierException("create object fail, class: " + targetClass.getName(), e);
        }
    }
}